from django.db import models
from django.contrib.auth import get_user_model
from django.core.validators import MinValueValidator, MaxValueValidator
from ckeditor.fields import RichTextField

User = get_user_model()


class ScenicCategory(models.Model):
    """景点分类"""
    name = models.CharField(max_length=200, verbose_name='分类名称')
    description = models.TextField(blank=True, verbose_name='分类描述')

    # 自关联字段 - 用于多级分类
    parent = models.ForeignKey(
        'self',
        on_delete=models.CASCADE,
        blank=True,
        null=True,
        related_name='children',
        verbose_name='父级分类'
    )

    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')

    class Meta:
        verbose_name = '景点分类'
        verbose_name_plural = '景点分类'
        ordering = ['name']

    def __str__(self):
        return self.name


class SentimentTag(models.Model):
    """情感标签"""
    name = models.CharField(verbose_name="标签名称", max_length=200, unique=True)
    sentiment_type = models.CharField(
        max_length=10,
        choices=[
            ('positive', '正面'),
            ('neutral', '中性'),
            ('negative', '负面')
        ],
        verbose_name='情感类型'
    )
    color = models.CharField(max_length=7, default='#6c757d', verbose_name='标签颜色')

    class Meta:
        verbose_name = '情感标签'
        verbose_name_plural = '情感标签'

    def __str__(self):
        return f"{self.name} ({self.get_sentiment_type_display()})"


class TouristAttraction(models.Model):
    """旅游景点"""
    # 基础信息
    name = models.CharField(max_length=200, verbose_name='景点名称')
    description = RichTextField(verbose_name='景点描述')
    location = models.CharField(max_length=200, verbose_name='地理位置')
    city = models.CharField(max_length=100, verbose_name='所在城市')
    province = models.CharField(max_length=100, verbose_name='所在省份')

    # 图片信息
    main_image = models.ImageField(upload_to='attractions/', verbose_name='主图')
    gallery_images = models.JSONField(default=list, blank=True, verbose_name='图集')

    # 分类和标签
    categories = models.ManyToManyField(
        verbose_name="所属分类",
        to='ScenicCategory',
        blank=True
    )
    sentiment_tags = models.ManyToManyField(
        verbose_name="情感标签",
        to='SentimentTag',
        blank=True
    )

    # 舆情分析字段
    avg_sentiment_score = models.FloatField(
        default=0.0,
        validators=[MinValueValidator(-1.0), MaxValueValidator(1.0)],
        verbose_name='平均情感得分'
    )
    heat_index = models.IntegerField(default=0, verbose_name='热度指数')
    review_count = models.IntegerField(default=0, verbose_name='评论数量')

    # 统计字段
    positive_count = models.IntegerField(default=0, verbose_name='正面评价数')
    neutral_count = models.IntegerField(default=0, verbose_name='中性评价数')
    negative_count = models.IntegerField(default=0, verbose_name='负面评价数')

    # 状态管理
    STATUS_CHOICES = (
        ('published', '已发布'),
        ('draft', '草稿'),
        ('pending', '待审核'),
        ('rejected', '已驳回'),
    )
    status = models.CharField(
        verbose_name="审核状态",
        max_length=10,
        choices=STATUS_CHOICES,
        default='pending'
    )

    # 管理信息
    created_by = models.ForeignKey(
        verbose_name="创建人",
        to=User,
        on_delete=models.CASCADE,
        related_name='created_attractions'
    )
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')

    class Meta:
        verbose_name = '旅游景点'
        verbose_name_plural = '旅游景点'
        ordering = ['-heat_index', '-created_at']

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        from django.urls import reverse
        return reverse('main:attraction_detail', kwargs={'pk': self.pk})

    def update_sentiment_stats(self):
        """更新情感统计信息"""
        from django.db.models import Avg, Count

        # 获取该景点的评论统计
        stats = SentimentComment.objects.filter(attraction=self, is_active=True).aggregate(
            avg_score=Avg('sentiment_score'),
            pos_count=Count('id', filter=models.Q(sentiment_label=SentimentComment.POSITIVE)),
            neu_count=Count('id', filter=models.Q(sentiment_label=SentimentComment.NEUTRAL)),
            neg_count=Count('id', filter=models.Q(sentiment_label=SentimentComment.NEGATIVE)),
            total_count=Count('id')
        )

        # 更新字段
        self.avg_sentiment_score = stats['avg_score'] or 0.0
        self.positive_count = stats['pos_count'] or 0
        self.neutral_count = stats['neu_count'] or 0
        self.negative_count = stats['neg_count'] or 0
        self.review_count = stats['total_count'] or 0

        # 计算热度指数
        self.heat_index = self.review_count * 10 + int((self.avg_sentiment_score + 1) * 50)
        self.save()


class SentimentComment(models.Model):
    """情感评论"""
    # 情感标签选择
    POSITIVE = 'positive'
    NEUTRAL = 'neutral'
    NEGATIVE = 'negative'
    SENTIMENT_CHOICES = [
        (POSITIVE, '积极'),
        (NEUTRAL, '中性'),
        (NEGATIVE, '负面'),
    ]

    # 来源平台选择
    WEBSITE = 'website'
    WEIBO = 'weibo'
    DOUBAN = 'douban'
    XIAOHONGSHU = 'xiaohongshu'
    SOURCE_CHOICES = [
        (WEBSITE, '网站用户'),
        (WEIBO, '微博'),
        (DOUBAN, '豆瓣'),
        (XIAOHONGSHU, '小红书'),
    ]

    # 关联关系
    attraction = models.ForeignKey(
        TouristAttraction,
        on_delete=models.CASCADE,
        related_name='sentiment_comments',
        verbose_name='关联景点'
    )
    author = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        verbose_name='评论用户'
    )

    # 评论内容
    content = models.TextField('评论内容', max_length=1000)
    rating = models.IntegerField(
        validators=[MinValueValidator(1), MaxValueValidator(5)],
        verbose_name='评分(1-5星)',
        default=3
    )

    # 情感分析字段
    sentiment_score = models.FloatField(
        default=0.0,
        validators=[MinValueValidator(-1.0), MaxValueValidator(1.0)],
        verbose_name='情感得分'
    )
    sentiment_label = models.CharField(
        max_length=10,
        choices=SENTIMENT_CHOICES,
        default=NEUTRAL,
        verbose_name='情感标签'
    )

    # 来源信息
    source_platform = models.CharField(
        max_length=20,
        choices=SOURCE_CHOICES,
        default=WEBSITE,
        verbose_name='来源平台'
    )

    # 时间信息
    created_at = models.DateTimeField('创建时间', auto_now_add=True)
    updated_at = models.DateTimeField('更新时间', auto_now=True)
    commented_at = models.DateTimeField('评论时间', auto_now_add=True)

    # 状态管理
    is_active = models.BooleanField('是否有效', default=True)
    is_auto_collected = models.BooleanField('自动采集', default=False)

    # 评论层级
    parent = models.ForeignKey(
        'self',
        on_delete=models.CASCADE,
        blank=True,
        null=True,
        related_name='replies',
        verbose_name='父评论'
    )

    class Meta:
        verbose_name = '景点评论'
        verbose_name_plural = '景点评论'
        ordering = ['-commented_at']

    def __str__(self):
        return f'{self.author.username} 评论了 {self.attraction.name}'

    @property
    def is_root(self):
        """判断是否为根评论"""
        return self.parent is None

    @property
    def has_replies(self):
        """判断是否有回复"""
        return self.replies.exists()

    def analyze_sentiment(self):
        """简单的情感分析"""
        positive_words = ['好', '棒', '美', '推荐', '喜欢', '漂亮', '不错', '值得', '满意']
        negative_words = ['差', '坑', '贵', '失望', '垃圾', '糟糕', '别去', '后悔', '不行']

        content_lower = self.content.lower()
        positive_count = sum(1 for word in positive_words if word in content_lower)
        negative_count = sum(1 for word in negative_words if word in content_lower)

        if positive_count > negative_count:
            self.sentiment_score = 0.8
            self.sentiment_label = self.POSITIVE
        elif negative_count > positive_count:
            self.sentiment_score = -0.8
            self.sentiment_label = self.NEGATIVE
        else:
            self.sentiment_score = 0.0
            self.sentiment_label = self.NEUTRAL

    def save(self, *args, **kwargs):
        # 自动分析情感
        if not self.sentiment_score and self.content:
            self.analyze_sentiment()

        super().save(*args, **kwargs)

        # 更新关联景点的统计信息
        if self.is_active:
            self.attraction.update_sentiment_stats()